import random
import struct,numpy as np

def dataReader(image_filename, label_filename, batch_size, drop_last=False):
    with open(image_filename,'rb') as image_file:
        img_buf = image_file.read()
        with open(label_filename,'rb') as label_file:
            lab_buf = label_file.read()
            step_label = 0
            offset_img = 0
            magic_byte_img = ">IIII"
            magic_img, image_num, rows, cols = struct.unpack_from(magic_byte_img,img_buf,offset_img)
            offset_img += struct.calcsize(magic_byte_img)

            offset_lab = 0
            magic_byte_lab = ">II"
            magic_lab, label_num = struct.unpack_from(magic_byte_lab, lab_buf, offset_lab)
            offset_lab += struct.calcsize(magic_byte_lab)

            if step_label >= label_num:
                raise ValueError('Invalid train data file')

            fmt_label = '>' + str(label_num) + 'B'
            labels = struct.unpack_from(fmt_label, lab_buf, offset_lab)

            fmt_imges = '>' + str(image_num * rows * cols) + 'B'
            images_temp = struct.unpack_from(fmt_imges, img_buf, offset_img)
            # 将长向量转为28*28的矩阵
            images = np.reshape(images_temp,(image_num,rows * cols)).astype('float32')
            # 数据归一化（-1，1）
            images = images / 255.0
            images = images * 2.0
            images = images - 1.0
            buf = []
            for i in range(image_num):
                buf.append((images[i,:],int(labels[i])))

    def batch_reader():
        # 样本数据打乱
        random.shuffle(buf)
        # 每次迭代提供 batch_size 个样本
        b = []
        for instance in buf:
            b.append(instance)
            if len(b) == batch_size:
                yield b
                b = []
        if drop_last is False and len(b) != 0:
            yield b

    batch_size = int(batch_size)
    return batch_reader()




